package launcher;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import multicast.MulticastCommsClient;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;

import announcer.AnnoucerScheduledTask;

import tcp.command.CommandManager;
import tcp.filetransfer.FileTransferManager;
import tcp.heartbeat.HeartbeatListener;
import constants.FileNodeConstants;
import filestorage.FileStorageManager;

public class FileNodeLauncher {
	public static void main(String[] args) {
		CommandLineParser parser = new PosixParser();
		CommandLineParameters params = new CommandLineParameters();
		CommandLine commandLine = null;
		try {
			
			commandLine = parser.parse(params.getCommandLineOptions(), args);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Map<String,String> propertiesForFileNode = params.getFileNodeParameters(commandLine);
		Map<String,String> properters = new HashMap<String, String>();
		properters.putAll(propertiesForFileNode);
		launchFileNode(propertiesForFileNode);
		incrementProperties(properters);
		launchFileNode2(properters);
		System.out.println("Test");
		/*HeartbeatListener hbListener = new HeartbeatListener(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_HB_PORT)));
		ExecutorService service = Executors.newSingleThreadExecutor();
		service.execute(hbListener);
		FileStorageManager fsManager = new FileStorageManager();
		FileTransferManager ftManager = new FileTransferManager(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_FU_PORT)),Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_FD_PORT)));
		ftManager.setFileHandler(fsManager);
		CommandManager commandManager = new CommandManager(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_COMMAND_PORT)));
		commandManager.setStatusHandler(fsManager);
		commandManager.setDeleteFileHandler(fsManager);
		commandManager.setReplicationHandler(fsManager);
		AnnoucerScheduledTask announcer = new AnnoucerScheduledTask(propertiesForFileNode);
		//Once each service has started, announce the system is alive
		MulticastCommsClient mcc = new MulticastCommsClient();
		mcc.sendMessage("ANNOUNCEFS:"+mcc.getMyAddress().getHostName()+":HB|"+propertiesForFileNode.get(FileNodeConstants.PARAM_HB_PORT)+":FU|"+propertiesForFileNode.get(FileNodeConstants.PARAM_FU_PORT)+":FD|"+propertiesForFileNode.get(FileNodeConstants.PARAM_FD_PORT)+":CP|"+propertiesForFileNode.get(FileNodeConstants.PARAM_COMMAND_PORT)) ;*/

	}
	public static void incrementProperties(Map<String,String> propertiesForFileNode){
		Set<String> setOfProperties = propertiesForFileNode.keySet();
		Iterator<String>iter = setOfProperties.iterator();
		while(iter.hasNext()){
			String key = iter.next();
			int portNumber = Integer.parseInt(propertiesForFileNode.get(key));
			portNumber++;
			propertiesForFileNode.put(key, ""+portNumber);
		}
	}
	public static void launchFileNode(Map<String,String> propertiesForFileNode){
		HeartbeatListener hbListener = new HeartbeatListener(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_HB_PORT)));
		ExecutorService service = Executors.newSingleThreadExecutor();
		service.execute(hbListener);
		FileStorageManager fsManager = new FileStorageManager();
		FileTransferManager ftManager = new FileTransferManager(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_FU_PORT)),Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_FD_PORT)));
		ftManager.setFileHandler(fsManager);
		CommandManager commandManager = new CommandManager(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_COMMAND_PORT)));
		commandManager.setStatusHandler(fsManager);
		commandManager.setDeleteFileHandler(fsManager);
		commandManager.setReplicationHandler(fsManager);
		AnnoucerScheduledTask announcer = new AnnoucerScheduledTask(propertiesForFileNode);
		//Once each service has started, announce the system is alive
		MulticastCommsClient mcc = new MulticastCommsClient();
		mcc.sendMessage("ANNOUNCEFS:"+mcc.getMyAddress().getHostName()+":HB|"+propertiesForFileNode.get(FileNodeConstants.PARAM_HB_PORT)+":FU|"+propertiesForFileNode.get(FileNodeConstants.PARAM_FU_PORT)+":FD|"+propertiesForFileNode.get(FileNodeConstants.PARAM_FD_PORT)+":CP|"+propertiesForFileNode.get(FileNodeConstants.PARAM_COMMAND_PORT)) ;
	}
	public static void launchFileNode2(Map<String,String> propertiesForFileNode){
		HeartbeatListener hbListener = new HeartbeatListener(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_HB_PORT)));
		ExecutorService service = Executors.newSingleThreadExecutor();
		service.execute(hbListener);
		FileStorageManager fsManager = new FileStorageManager("C:\\storage-two");
		FileTransferManager ftManager = new FileTransferManager(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_FU_PORT)),Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_FD_PORT)));
		ftManager.setFileHandler(fsManager);
		CommandManager commandManager = new CommandManager(Integer.parseInt(propertiesForFileNode.get(FileNodeConstants.PARAM_COMMAND_PORT)));
		commandManager.setStatusHandler(fsManager);
		commandManager.setDeleteFileHandler(fsManager);
		commandManager.setReplicationHandler(fsManager);
		AnnoucerScheduledTask announcer = new AnnoucerScheduledTask(propertiesForFileNode);
		//Once each service has started, announce the system is alive
		MulticastCommsClient mcc = new MulticastCommsClient();
		mcc.sendMessage("ANNOUNCEFS:"+mcc.getMyAddress().getHostName()+":HB|"+propertiesForFileNode.get(FileNodeConstants.PARAM_HB_PORT)+":FU|"+propertiesForFileNode.get(FileNodeConstants.PARAM_FU_PORT)+":FD|"+propertiesForFileNode.get(FileNodeConstants.PARAM_FD_PORT)+":CP|"+propertiesForFileNode.get(FileNodeConstants.PARAM_COMMAND_PORT)) ;
	}
}
